﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Controls;

using PlanningGIS.Util.Convertor;
using PlanningGIS.ArcGIS;
using PlanningGIS.Util.Log;
using PlanningGIS.Engine.Controls;

namespace PlanningGIS.DataCheck.model
{
    /// <summary>
    /// 管线连贯检查（查图形上实接的两个管线要素的描述字段属性是否不一致。注：指首尾，首首或尾尾相连，不包括中间生出的枝杈）
    /// </summary>
    public class PipeConsistencyCheck : Check
    {
        public int Check(string errType, IFeatureLayer pFeatLyr, IGeometry pGeometry, string whereClause, string fdescname)
        {
            IFeatureClass pFeatCls = pFeatLyr.FeatureClass;
            if (pFeatCls.ShapeType != esriGeometryType.esriGeometryPolyline)
            {
               LogHelper.WriteErrLog("[" + pFeatLyr.Name + "图层不是线状图层，检查失败！");
                return -1;
            }
            
            int idxfdesc = pFeatCls.FindField(fdescname);
            if (idxfdesc == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyr.Name + "图层中未找到描述[" + fdescname + "]字段，检查失败！");
                return -1;
            }

            ISpatialFilter pSpatialFileter = new SpatialFilterClass();
            if (pGeometry != null) pSpatialFileter.Geometry = pGeometry;

            string sql = fdescname + " <> ' ' and not " + fdescname + " is null";
            pSpatialFileter.WhereClause = whereClause == "" ? sql : whereClause + " and " + sql;

            pSpatialFileter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            pSpatialFileter.GeometryField = pFeatCls.ShapeFieldName;

            showFakePro(true);
            LogHelper.WriteLog("正在计算需要检查的要素数目...");

            int max = FeatureClassHelper.GetFeatureCountFromLayer(pFeatLyr,pSpatialFileter);// pFeatCls.FeatureCount(pSpatialFileter);

            LogHelper.WriteLog("计算完毕。共有" + max + "个要素参与检查。");
            showFakePro(false);

            if (max == 0)
            {
                LogHelper.WriteLog("没有满足检查要求的要素存在。");
                return -1;
            }

            setProcessBarMax(max);

            IFeatureCursor pFeatCur;
            pFeatCur = pFeatLyr.Search(pSpatialFileter, false);

            IFeature pFeature;

            int count = 0;
            int errCount = 0;

            //记录检查过的点，下次遇到直接跳过
            IPointCollection pPoints = new MultipointClass();
            IRelationalOperator pRel = pPoints as IRelationalOperator;

            object missing = Type.Missing;

            while ((pFeature = pFeatCur.NextFeature()) != null)
            {
                if (IsStop()) break;

                setProcessBarCurrent(count);
                count++;

                IPolyline pPolyline = pFeature.ShapeCopy as IPolyline;
                IPoint pFromPoint = pPolyline.FromPoint;
                IPoint pToPoint = pPolyline.ToPoint;

                string fdescvalue = StringHelper.ConvertWRTNull(pFeature.get_Value(idxfdesc));
                if (fdescvalue == "0") fdescvalue = "";

                IFeature pFeatRst;

                if (!pRel.Contains(pFromPoint))
                {
                    pPoints.AddPoint(pFromPoint, ref missing, ref missing);
                    pFeatRst=CheckPoint(pFromPoint, pFeatLyr,fdescvalue, idxfdesc);
                    if (pFeatRst!=null)
                    {
                        RecordListHelper.AddRecordItem(errType, pFeatLyr, null, pFeature, pFeatRst, pFromPoint, "");
                        errCount++;
                    }
                }

                if (!pRel.Contains(pToPoint))
                {
                    pPoints.AddPoint(pToPoint, ref missing, ref missing);
                    pFeatRst = CheckPoint(pToPoint, pFeatLyr, fdescvalue, idxfdesc);
                    if (pFeatRst != null)
                    {
                        RecordListHelper.AddRecordItem(errType, pFeatLyr, null, pFeature, pFeatRst, pToPoint, "");
                        errCount++;
                    }
                }

            }

            finishPro.Invoke();

            DataCheckUtility.ReleaseComObject(pFeature);
            DataCheckUtility.ReleaseComObject(pFeatCur);

            LogHelper.WriteLog("管线属性异常检查结束。共发现" + errCount + "处错误！\n");

            return errCount;
        }

        private IFeature CheckPoint(IPoint pPoint, IFeatureLayer pFeatLyr, string fdescvalue, int idxfdesc)
        {
            IFeatureClass pFeatCls = pFeatLyr.FeatureClass;
            IFeatureCursor pFeatCur = CursorHelper.GetCursor(pFeatCls, pPoint, "", esriSpatialRelEnum.esriSpatialRelTouches);
            IFeature pFeature;

            while ((pFeature = pFeatCur.NextFeature()) != null)
            {
                //"0"、""和NULL是一回事
                string fdescvalue2 = StringHelper.ConvertWRTNull(pFeature.get_Value(idxfdesc));
                if (fdescvalue2 == "0") fdescvalue2 = "";

                if (fdescvalue != fdescvalue2)
                {
                    DataCheckUtility.ReleaseComObject(pFeatCur);
                    return pFeature;
                }

            }
            DataCheckUtility.ReleaseComObject(pFeatCur);
            return null;
        }
    }
}
